package com.ccsc.auth.controller;

import com.ccsc.auth.entity.Resource;
import com.ccsc.auth.entity.Role;
import com.ccsc.auth.entity.Systems;
import com.ccsc.auth.entity.vi.RoleVi;
import com.ccsc.auth.entity.vo.ResourceVo;
import com.ccsc.auth.entity.vo.RoleVo;
import com.ccsc.auth.entity.vo.SystemsVo;
import com.ccsc.auth.service.ResourceService;
import com.ccsc.auth.service.RoleService;
import com.ccsc.auth.service.SystemsService;
import com.ccsc.auth.utils.BaseResponse;
import com.ccsc.auth.utils.DataMap;
import com.ccsc.auth.utils.Page;
import com.google.common.collect.Lists;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by yyangs on 2017/2/17.
 */
@RestController
@RequestMapping("/roleManage")
public class RoleController extends BaseController {
    @Autowired
    private RoleService roleService;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private SystemsService systemsService;

    //获取全部角色信息通过列表分页
    @RequestMapping(value = "/rolesBypages", method = RequestMethod.GET, produces = {"application/json", "application/xml"})
    public BaseResponse getAllRoleBypages(WebRequest request,
                                          @RequestParam(required =true,defaultValue ="1")int page,
                                          @RequestParam(required =true,defaultValue ="5")int pageSize) throws Exception {
        DataMap params = getParam(request);
        params.put("page", page);
        params.put("pageSize", pageSize);
        try {
            Page pageList = roleService.getRolesByPage(params);
            List<Role> roleList = pageList.getContent();
            List<RoleVo> roleVoList = Lists.newArrayList();
            if(roleList!=null && roleList.size() > 0){
                int i=1+(params.getInt("page")-1)*params.getInt("pageSize");
                for(Role role : roleList){
                    RoleVo roleVo=role2RoleVo(role);
                    roleVo.setNum(i++);
                    List<Resource> resourceList=resourceService.getResourcesByRoleId(role.getId());
                    List<ResourceVo> resourceVoList=new ArrayList<>();
                    for (Resource resource:resourceList) {
                        ResourceVo resourceVo=resource2ResourceVo(resource);
                        resourceVoList.add(resourceVo);
                    }
                    roleVo.setResourceList(resourceVoList);
                    roleVo.setUsernumber(roleService.getUserNumByRoleId(role.getId()));
                    roleVoList.add(roleVo);
                }
            }
            pageList.setContent(roleVoList);
            return this.ok(pageList);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //获取全部角色信息
    @RequestMapping(value = "/roles", method = RequestMethod.GET, produces = {"application/json", "application/xml"})
    public BaseResponse getAllRole(WebRequest request) throws Exception {
        try {
            List<RoleVo> roleVoList = Lists.newArrayList();
            List<Role> roleList = roleService.getAllRoles();
            if(roleList!=null && roleList.size()>0){
                for(Role role : roleList){
                    RoleVo roleVo = new RoleVo();
                    BeanUtils.copyProperties(roleVo, role);
                    roleVoList.add(roleVo);
                }
            }
            return this.ok(roleVoList);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //查询角色详细信息根据id
    @RequestMapping(value = "/role/{roleIdIn}", method = RequestMethod.GET, produces = {"application/json", "application/xml"})
    public BaseResponse getRoleById(@PathVariable("roleIdIn")String roleIdIn) throws Exception {
        Integer roleId=Integer.parseInt(roleIdIn);
        try {
            Role role=roleService.getRoleById(roleId);
            RoleVo roleVo = new RoleVo();
            BeanUtils.copyProperties(roleVo, role);
            return this.ok(role);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //添加新角色
    @RequestMapping(value = "/role", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
    public BaseResponse addRole(@Valid @RequestBody RoleVi roleVi, BindingResult bindingResult) throws Exception {
        try {
            Integer result=0;
            List<Role> roleList=roleService.getRolesByName(roleVi.getName());
            //不能重名和资源为空
            if(roleList.size()>0&&roleVi.getResourceList()==null) {
                return this.error(500, "角色名称已存在，添加失败");
            }
            Role role = roleVi2Role(roleVi);
            result = roleService.createRole(role);
            return this.ok(result);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //获取所有资源信息
    @RequestMapping(value = "/resource", method = RequestMethod.GET, produces = {"application/json", "application/xml"})
    public BaseResponse getAllResources(WebRequest request) throws Exception {
        try {
            Integer result=0;
            //获取所有的资源
            List<Resource> resourceList=resourceService.getAllResources();
            return this.ok(resourceList);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //获取所有的系统信息
    @RequestMapping(value = "/systems", method = RequestMethod.GET, produces = {"application/json", "application/xml"})
    public BaseResponse getAllSystems(WebRequest request) throws Exception {
        try {
            Integer result=0;
            //获取所有的资源
            List<Systems> systemsList=systemsService.getAllSystemses();
            List<SystemsVo> systemsVoList=new ArrayList<>();
            for (Systems system:systemsList) {
                SystemsVo systemsVo=systems2SystemsVo(system);
                List<Resource> resourceList=resourceService.getResourcesBySystemsId(system.getId());
                List<ResourceVo> resourceVos=new ArrayList<>();
                for (Resource resource:resourceList) {
                    ResourceVo resourceVo=resource2ResourceVo(resource);
                    resourceVos.add(resourceVo);
                }
                //添加层级关系
                systemsVo.setResourceList(resourceList2ChildList(resourceVos, null));
                systemsVoList.add(systemsVo);
            }
            return this.ok(systemsVoList);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //修改角色
    @RequestMapping(value = "/role/{roleIdIn}", method = RequestMethod.PUT, produces = {"application/json", "application/xml"})
    public BaseResponse updateRole(@PathVariable("roleIdIn")String roleIdIn, @Valid @RequestBody RoleVi roleVi, BindingResult bindingResult) throws Exception {
        try {
            Integer result=0;
            roleVi.setId(Integer.parseInt(roleIdIn));
            Role roleTemp=roleService.getRoleById(roleVi.getId());
            if(roleTemp == null) {
                return this.error(500, "角色不存在，修改失败");
            }
            List<Role> roleList=roleService.getRolesByName(roleTemp.getName());
            //不能重名和资源为空
            if(roleList.size()==1&&roleList.get(0).getId()!=roleTemp.getId()||roleList.size()>1) {
                return this.error(500, "角色名称已存在，修改失败");
            }
            Role role =roleVi2Role(roleVi);
            result = roleService.updateRole(role);
            return this.ok(result);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    //删除角色
    @RequestMapping(value = "/role/{roleIdIn}", method = RequestMethod.DELETE, produces = {"application/json", "application/xml"})
    public BaseResponse deleteRole(@PathVariable("roleIdIn")String roleIdIn) throws Exception {
        Integer roleId=Integer.parseInt(roleIdIn);
        try {
            Integer result=0;
            Role role = roleService.getRoleById(roleId);
            if(role!=null) {
                result= roleService.deleteRoleById(roleId);
            }
            return this.ok(result);
        }catch (Exception e){
            e.printStackTrace();
            return this.error(500, e.getMessage());
        }
    }

    public static SystemsVo systems2SystemsVo(Systems systems){
        SystemsVo systemsVo=new SystemsVo();
        systemsVo.setId(systems.getId());
        systemsVo.setName(systems.getName());
        systemsVo.setDescription(systems.getDescription());
        systemsVo.setUrl(systems.getUrl());
        return systemsVo;
    }

    public static ResourceVo resource2ResourceVo(Resource resource){
        ResourceVo resourceVo=new ResourceVo();
        resourceVo.setId(resource.getId());
        resourceVo.setName(resource.getDescription());
        resourceVo.setContent(resource.getContent());
        resourceVo.setpId(resource.getParentResource()!=null ? resource.getParentResource().getId() : null);
        resourceVo.setDescription(resource.getDescription());
        return resourceVo;
    }

    public static RoleVo role2RoleVo(Role role){
        RoleVo roleVo=new RoleVo();
        roleVo.setId(role.getId());
        roleVo.setName(role.getName());
        roleVo.setDescription(role.getDescription());
        roleVo.setStatus(role.getStatus());
        return roleVo;
    }
    public static Role roleVi2Role(RoleVi roleVi){
        Role role=new Role();
        role.setId(roleVi.getId());
        role.setName(roleVi.getName());
        role.setDescription(roleVi.getDescription());
        List<Resource> resourceList=new ArrayList<>();
        for (Integer resourceId:roleVi.getResourceList()) {
            Resource resource=new Resource();
            resource.setId(resourceId);
            resourceList.add(resource);
        }
        role.setResourceList(resourceList);
        return role;
    }

    /**
     *将平行的资源树转化层级资源树
     * @param resourceList
     * @param parentNum
     * @return
     */
    public static List<ResourceVo> resourceList2ChildList(List<ResourceVo> resourceList, Integer parentNum){
        List<ResourceVo> temp=new LinkedList<ResourceVo>();
        if(resourceList.size()==0){return null;}
        for (int i=0; i<resourceList.size(); i++) {
            if(resourceList.size()==0){break;}
            ResourceVo resourceVo = resourceList.get(i);
            if(parentNum!=null) {
                if(resourceVo.getpId()==null || resourceVo.getpId() == 0){continue;}
                if (parentNum==resourceVo.getpId()) {
                    resourceList.remove(i);
                    i--;
                    resourceVo.setResourceList(resourceList2ChildList(resourceList, resourceVo.getId()));
                    temp.add(resourceVo);
                }
            }else {
                if (resourceVo.getpId()==null || resourceVo.getpId() == 0) {
                    resourceList.remove(i);
                    i--;
                    resourceVo.setResourceList(resourceList2ChildList(resourceList, resourceVo.getId()));
                    temp.add(resourceVo);
                }
            }
        }
        return temp;
    }
}
